﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Xml;
#endregion // Using Statements

namespace ParticleSystem
{
    /// <summary>
    /// Defines a force that will act upon the world.
    /// </summary>
    public class Force
    {
        #region Fields

        /// <summary>
        /// The name of this force.
        /// </summary>
        private string mName;
        public string name
        {
            get { return mName; }
        }

        /// <summary>
        /// The magnitude of this force.
        /// </summary>
        private float mMagnitude;
        public float magnitude
        {
            get { return mMagnitude; }
        }

        /// <summary>
        /// The direction of this force.
        /// </summary>
        private Vector3 mDirection;
        public Vector3 direction
        {
            get { return mDirection; }
        }

        /// <summary>
        /// Flag indicating whether or not this is a resistance force.
        /// </summary>
        private bool mIsResistance;

        public Vector3 getActingForce(Vector3 objectVelocity)
        {
            if (mIsResistance)
                return ((mDirection * mMagnitude) - objectVelocity) * 0.35f;
            else
                return mDirection * mMagnitude;
        }

        #endregion // Fields

        #region Force Constructors
        /// <summary>
        /// Force constructor.
        /// </summary>
        /// <param name="name">The name of this force.</param>
        /// <param name="magnitude">The magnitude of this force.</param>
        /// <param name="direction">The direction of this force.</param>
        /// <param name="isResistance">Whether or not this force is a resistance force.</param>
        public Force(string name, float magnitude, Vector3 direction, bool isResistance = false)
        {
            mName = name;
            mMagnitude = magnitude;
            mDirection = (direction == Vector3.Zero) ? direction : Vector3.Normalize(direction);
            mIsResistance = isResistance;
        }

        /// <summary>
        /// Create a force from an XML element.
        /// </summary>
        /// <param name="forceXmlElement">The XML element defining this force.</param>
        /// <returns>The force constructed from the XML element.</returns>
        public static Force ForceFromXml(XmlElement forceXmlElement)
        {
            // get force name
            String forceName = forceXmlElement.GetAttribute("name");
            if(forceName == null)
                forceName = "NoName";

            float magnitude = 0.0f;
            Vector3 direction = Vector3.Zero;
            bool isResistance = false;

            foreach (XmlElement childElement in forceXmlElement)
            {
                // found magnitude
                if(childElement.Name.Equals("magnitude"))
                {
                    magnitude = float.Parse(childElement.ChildNodes[0].Value);
                }
                // found direction
                else if (childElement.Name.Equals("direction"))
                {
                    direction = Utility.Vector3FromXml(childElement);
                }
                // found resistance flag
                else if (childElement.Name.Equals("isResistance"))
                {
                    isResistance = bool.Parse(childElement.ChildNodes[0].Value);
                }
            }

            return new Force(forceName, magnitude, direction, isResistance);
        }
        #endregion // Force Constructors
    }
}
